/*
 ------------------------------------------------------------------------------
 Copyright (C) 2009-2011 Eternal Games.

 This file is part of the Eternal Tech source code.

 The Eternal Tech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Eternal Tech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Eternal Tech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// g_event.cpp - Functions that sits in a frame loop, waiting for something to happen
//


#include "g_local2.h"
#include "g_local.h"


enum monsterType_t {
	MT_SOLDIER_LIGHT,
	MT_SOLDIER_SHOTGUN,
	MT_SOLDIER_MACHINEGUN,
	MT_INFANTRY,
	MT_PARASITE,
	MT_GUNNER,
	MT_BERSERKER,
	MT_MEDIC,
	MT_TANK,
	MT_CHICK,
	MT_MUTANT,
	MT_BRAIN,
	MT_TOTAL
};

struct monsterTable_t {
	const char				*name;
	monsterType_t			type;
	vec3_t					mins, maxs;
};

static monsterTable_t	g_monsterTable[] = {
	{"monster_soldier_light",		MT_SOLDIER_LIGHT,			{-16, -16, -24},  {16, 16, 32}},
	{"monster_soldier",				MT_SOLDIER_SHOTGUN,			{-16, -16, -24},  {16, 16, 32}},
	{"monster_soldier_ss",			MT_SOLDIER_MACHINEGUN,		{-16, -16, -24},  {16, 16, 32}},
	{"monster_infantry",			MT_INFANTRY,				{-16, -16, -24},  {16, 16, 32}},
	{"monster_parasite",			MT_PARASITE,				{-16, -16, -24},  {16, 16, 24}},
	{"monster_gunner",				MT_GUNNER,					{-16, -16, -24},  {16, 16, 32}},
	{"monster_berserk",				MT_BERSERKER,				{-16, -16, -24},  {16, 16, 32}},
	{"monster_medic",				MT_MEDIC,					{-24, -24, -24},  {24, 24, 32}},
	{"monster_tank",				MT_TANK,					{-32, -32, -16},  {32, 32, 72}},
	{"monster_chick",				MT_CHICK,					{-16, -16,   0},  {16, 16, 56}},
	{"monster_mutant",				MT_MUTANT,					{-32, -32, -24},  {32, 32, 48}},
	{"monster_brain",				MT_BRAIN,					{-16, -16, -24},  {16, 16, 32}},
};


/*
 ==============================================================================

    MONSTER GENERATOR SPAWNING

 ==============================================================================
*/


/*
 ==================
 G_SpawnMonsters

 TODO: Add a debug variable for X amount of spawned monsters
 TODO2: Spawn an X amount of monsters based on how many players are active
 TODO3: Spawn bosses and flying monsters
 TODO4: Use g_debugSpawnedMonsters for totalSpawnedMonsters
 TODO5: Add a check that stops the function if there are no generators or if the editor is active
 ==================
*/
void G_SpawnMonsters ()
{
	monsterTable_t   *monsterTable;
	edict_t			 *list[1], *edict;
	vec3_t			 out, mins, maxs;
	bool			 validSpawn;
	int				 tries = 0, flags = 1;
	int				 edicts;

	if (!g_debugSpawnMonsters->integerValue)
		return;

	level.totalSpawnedMonsters = 10;

	// Spawn a random monster
	while ((level.totalSpawnedMonsters - level.numSpawnedMonsters) != 0){
		monsterTable = &g_monsterTable[rand() % MT_TOTAL];

		// Try to spawn a monster inside the generator
		while (tries < 100){
			validSpawn = gi.TestGeneratorBBox(monsterTable->mins, monsterTable->maxs, flags, out);

			VectorCopy(out, mins);
			VectorCopy(out, maxs);

			edicts = gi.BoxEdicts(mins, maxs, list, 1, AREA_SOLID);

			if (validSpawn && edicts == 0)
			{
				edict = G_Spawn();

				VectorCopy(out, edict->s.origin);
				edict->classname = (char *)monsterTable->name;
				edict->s.angles[1] = frand() * 360.0f;
				VectorCopy(mins, edict->mins);
				VectorCopy(maxs, edict->maxs);
				edict->s.scale = DEFAULT_MONSTER_SCALE;
				edict->Monster.Entity = edict;
				edict->Monster.Level = Characters_GetAverageLevel();
				edict->health = ((edict->health / 2) + (edict->health - (edict->health - (edict->Monster.Level / 3.5f)))) * DEFAULT_MONSTER_SCALE;
				edict->Monster.BaseExperience = (edict->health + ((edict->health / 3))) / 2;

				ED_CallSpawn(edict);

				gi.linkentity(edict);

				level.numSpawnedMonsters++;

				break;
			}

			// Try again
			tries++;
		}
	}
}